<?php


namespace app\admin\controller;


use app\admin\service\RbacService;
use app\common\controller\CommonController;
use app\common\exception\ParameterFailedException;
use app\common\exception\NotFoundException;
use app\common\model\MediaModel;
use app\common\model\ProductAttrGroup;
use app\common\model\ProductAttrGroupModel;
use app\common\model\ProductAttrModel;
use app\common\model\ProductCategoryModel;
use app\common\model\ProductModel;
use app\common\model\ProductSkuModel;
use app\common\service\Lang;
use app\common\validate\ProductValidate;
use PhpOffice\PhpWord\Media;
use think\facade\Db;

class ProductController extends CommonController
{
    public function getProductAttrGroupList()
    {
        $searchParams = self::getParam([]);
        $where        = [];
        foreach ($searchParams as $key => $value) {
            if (is_array($value) && $key === 'create_time') {
                $where[] = [
                    $key,
                    'between',
                    $value,
                ];
                continue;
            }
            if (strpos($value, '%') !== false) {
                $where[] = [
                    $key,
                    'like',
                    $value,
                ];
            }
            else {
                $where[] = [
                    $key,
                    '=',
                    $value,
                ];
            }
        }
        $where = [];
        $model = (new ProductAttrGroupModel())->with([
            'categoryInfo',
        ])->order([
            //            'sea_waybill_number' => 'desc',
            //            'case_number'        => 'desc',
            'create_time' => 'desc',
        ])->where($where)->paginate([
            'page'      => $this->page,
            'list_rows' => $this->limit,
        ]);
        return retJson(Lang::GETDone, $model->toArray());
    }

    public function postProductAttrGroup(): ?\think\response\Json
    {
        $params      = self::getParam([
            'attr_group_name',
            'attr_group_category_id',
        ]);
        (new ProductValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $oldModel = (new ProductAttrGroupModel())->where('name', $params['attr_group_name'])
                ->where('category_id', $params['attr_group_category_id'])
                ->find();
            if ($oldModel) {
                throw new ParameterFailedException(['msg' => '已存在该数据']);
            }

            $categoryModel = ProductCategoryModel::where('id', $params['attr_group_category_id'])->find();
            if (!$categoryModel) {
                throw new NotFoundException(['msg' => '分类数据不存在']);
            }

            $model              = new ProductAttrGroupModel();
            $model->name        = $params['attr_group_name'];
            $model->category_id = $params['attr_group_category_id'];

            $model->save();

            Db::commit();
            return retJson(Lang::POSTDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function putProductAttrGroup()
    {
        $params      = self::getParam([
            'attr_group_id',
            'attr_group_name',
            'attr_group_category_id',
        ]);
        (new ProductValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $model = ProductAttrGroupModel::where('id', $params['attr_group_id'])->find();
            if (!$model) {
                throw new NotFoundException();
            }

            $categoryModel = ProductCategoryModel::where('id', $params['attr_group_category_id'])->find();
            if (!$categoryModel) {
                throw new NotFoundException(['msg' => '分类数据不存在']);
            }

            $model->name        = $params['attr_group_name'];
            $model->category_id = $params['attr_group_category_id'];

            $model->save();

            Db::commit();
            return retJson(Lang::PUTDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function deleteProductAttrGroup(): ?\think\response\Json
    {
        $params      = self::getParam([
            'attr_group_id',
        ]);
        (new ProductValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $model = ProductAttrGroupModel::where('id', $params['attr_group_id'])->find();
            if (!$model) {
                throw new NotFoundException();
            }

            //要判断是否有商品spu关联，没有的话允许删除
            //            $productModel = ProductModel::where('category_id', $params['category_id'])->find();
            //            if ($productModel) {
            //                throw new NotFoundException(['msg' => '该数据已被绑定，请解除绑定后继续操作']);
            //            }

            $model->delete_time = NOW_TIME;
            $model->save();

            Db::commit();

            return retJson(Lang::DELETEDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function getProductCategoryList()
    {
        $searchParams = self::getParam([]);
        $where        = [];
        foreach ($searchParams as $key => $value) {
            if (is_array($value) && $key === 'create_time') {
                $where[] = [
                    $key,
                    'between',
                    $value,
                ];
                continue;
            }
            if (strpos($value, '%') !== false) {
                $where[] = [
                    $key,
                    'like',
                    $value,
                ];
            }
            else {
                $where[] = [
                    $key,
                    '=',
                    $value,
                ];
            }
        }
        $where = [];
        $model = (new ProductCategoryModel())->with([])->order([
            //            'sea_waybill_number' => 'desc',
            //            'case_number'        => 'desc',
            'create_time' => 'desc',
        ])->where($where)->paginate([
            'page'      => $this->page,
            'list_rows' => $this->limit,
        ]);
        return retJson(Lang::GETDone, $model->toArray());
    }

    public function postProductCategory(): ?\think\response\Json
    {
        $params      = self::getParam([
            'category_name',
        ]);
        (new ProductValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $oldModel = (new ProductCategoryModel())->where('name', $params['category_name'])->find();
            if ($oldModel) {
                throw new ParameterFailedException(['msg' => '已存在该数据']);
            }

            $model       = new ProductCategoryModel();
            $model->name = $params['category_name'];

            $model->save();

            Db::commit();
            return retJson(Lang::POSTDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function putProductCategory()
    {
        $params      = self::getParam([
            'category_id',
            'category_name',
        ]);
        (new ProductValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $model = ProductCategoryModel::where('id', $params['category_id'])->find();
            if (!$model) {
                throw new NotFoundException();
            }

            $model->name = $params['category_name'];
            $model->save();

            Db::commit();
            return retJson(Lang::PUTDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function deleteProductCategory(): ?\think\response\Json
    {
        $params      = self::getParam(['category_id']);
        (new ProductValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $model = ProductCategoryModel::where('id', $params['category_id'])->find();
            if (!$model) {
                throw new NotFoundException();
            }

            $productModel = ProductModel::where('category_id', $params['category_id'])->find();
            if ($productModel) {
                throw new NotFoundException(['msg' => '该数据已被绑定，请解除绑定后继续操作']);
            }

            $productAttrGroupModel = ProductAttrGroupModel::where('category_id', $params['category_id'])->find();
            if ($productAttrGroupModel) {
                throw new NotFoundException(['msg' => '该数据已被绑定，请解除绑定后继续操作']);
            }

            $model->delete_time = NOW_TIME;
            $model->save();

            Db::commit();

            return retJson(Lang::DELETEDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function getProductList()
    {
        $searchParams = self::getParam([]);
        $where        = [];
        foreach ($searchParams as $key => $value) {
            if (is_array($value) && $key === 'create_time') {
                $where[] = [
                    $key,
                    'between',
                    $value,
                ];
                continue;
            }
            if (strpos($value, '%') !== false) {
                $where[] = [
                    $key,
                    'like',
                    $value,
                ];
            }
            else {
                $where[] = [
                    $key,
                    '=',
                    $value,
                ];
            }
        }
        $where      = [];
        $model      = (new ProductModel())->getProductListPaginate($where, $this->page, $this->limit);
        $modelsArr  = $model->toArray();
        $modelsData = $modelsArr['data'];
        self::arrangeProduct($modelsData, true);
        //        var_dump($modelsArr);die;
        $modelsArr['data'] = $modelsData;
        return retJson(Lang::GETDone, $modelsArr);
    }

    public function postProduct()
    {
        Db::startTrans();
        try {
            $params      = self::getParam([
                'product_name',
                'product_category_id',
                'product_logo_url',
                'product_share_url',
                'product_wechat_share_url',
                'product_mini_share_url',
                'product_image_urls',
                'product_desc',
                'product_status',
                'product_sku',
                'product_attr_info',
                'product_gift_points_proportion',
                'product_tags',
            ]);
            (new ProductValidate())->goCheck(__FUNCTION__, $params);
            //检查规格 和 sku 是否对的上
            $skuNamesArr = [];

            #比对 笛卡尔积attr_info['sku_names'] <=> product_sku['sku_name']
            foreach ($params['product_attr_info'] as &$attrInfo) {
                sort($attrInfo['sku_names']);
                $attrsArr[]    = $attrInfo['attr'];
                $skuNamesArr[] = $attrInfo['sku_names'];
            }
            $skuNamesArr = cartesianProduct($skuNamesArr);
            //            vd($skuNamesArr);
            //            var_dump($attrNamesArr);die;
            if (count($params['product_sku']) !== count($skuNamesArr)) {
                throw new ParameterFailedException(['msg' => '商品SKU或商品规格错误']);
            }

            $skuSaveData = [];
            foreach ($params['product_sku'] as &$sku) {
                if (!in_array($sku['sku_name'], $skuNamesArr, true)) {
                    throw new ParameterFailedException(['msg' => '商品SKU或商品规格错误']);
                }
                $skuSaveData[] = [
                    'sku_name'      => $sku['sku_name'],
                    'price'         => $sku['price'],
                    'cost_price'    => $sku['cost_price'],
                    'stock'         => $sku['stock'],
                    'virtual_sales' => $sku['virtual_sales'],
                    'logo_url'      => $sku['logo_url'],
                ];
            }

            //查看是否有相同的商品
            $oldModel = (new ProductModel())->where('name', $params['product_name'])->find();
            if ($oldModel) {
                throw new ParameterFailedException(['msg' => '已存在该商品']);
            }

            //查看商品分类是否存在
            $categoryModel = (new ProductCategoryModel())->where('id', $params['product_category_id'])->find();
            if (!$categoryModel) {
                throw new ParameterFailedException(['msg' => '分类不存在']);
            }

            $model                         = new ProductModel();
            $model->name                   = $params['product_name'];
            $model->category_id            = $params['product_category_id'];
            $model->logo_url               = $params['product_logo_url'];
            $model->share_url              = $params['product_share_url'];
            $model->wechat_share_url       = $params['product_wechat_share_url'];
            $model->mini_share_url         = $params['product_mini_share_url'];
            $model->image_urls             = $params['product_image_urls'];
            $model->desc                   = $params['product_desc'];
            $model->gift_points_proportion = $params['product_gift_points_proportion'];
            $model->tags                   = $params['product_tags'];
            $model->attr_info              = $params['product_attr_info'];
            $model->status                 = $params['product_status'];
            $model->save();

            foreach ($skuSaveData as &$item) {
                $item['product_id'] = $model->id;
            }

            $skuModel = new ProductSkuModel();
            $skuModel->saveAll($skuSaveData);

            Db::commit();
            return retJson(Lang::POSTDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function putProduct()
    {
        Db::startTrans();
        try {
            $params      = self::getParam([
                'product_id',
                'product_name',
                'product_category_id',
                'product_logo_url',
                'product_share_url',
                'product_wechat_share_url',
                'product_mini_share_url',
                'product_image_urls',
                'product_desc',
                'product_status',
                'product_sku',
                'product_attr_info',
                'product_gift_points_proportion',
                'product_tags',
            ]);
            (new ProductValidate())->goCheck(__FUNCTION__, $params);
            //检查规格 和 sku 是否对的上
            $skuNamesArr = [];

            #比对 笛卡尔积attr_info['sku_names'] <=> product_sku['sku_name']
            foreach ($params['product_attr_info'] as &$attrInfo) {
                sort($attrInfo['sku_names']);
                $attrsArr[]    = $attrInfo['attr'];
                $skuNamesArr[] = $attrInfo['sku_names'];
            }
            $skuNamesArr = cartesianProduct($skuNamesArr);
            //            vd($skuNamesArr);
            //            var_dump($attrNamesArr);die;
            if (count($params['product_sku']) !== count($skuNamesArr)) {
                throw new ParameterFailedException(['msg' => '商品SKU或商品规格错误']);
            }

            $skuSaveData = [];
            foreach ($params['product_sku'] as &$sku) {
                if (!in_array($sku['sku_name'], $skuNamesArr, true)) {
                    throw new ParameterFailedException(['msg' => '商品SKU或商品规格错误']);
                }
                $skuSaveData[] = [
                    'sku_name'      => $sku['sku_name'],
                    'price'         => $sku['price'],
                    'cost_price'    => $sku['cost_price'],
                    'stock'         => $sku['stock'],
                    'virtual_sales' => $sku['virtual_sales'],
                    'logo_url'      => $sku['logo_url'],
                ];
            }

            //查看是否有相同的商品
            $oldModel = (new ProductModel())->where('name', $params['product_name'])->find();
            if ($oldModel && $oldModel->getData('id') !== (int)$params['product_id']) {
                throw new ParameterFailedException(['msg' => '已存在相同名称的商品']);
            }

            //查看商品分类是否存在
            $categoryModel = (new ProductCategoryModel())->where('id', $params['product_category_id'])->find();
            if (!$categoryModel) {
                throw new ParameterFailedException(['msg' => '分类不存在']);
            }

            $model = (new ProductModel())->where('id', $params['product_id'])->find();
            if (!$model) {
                throw new ParameterFailedException(['msg' => '商品不存在']);
            }
            $model->name                   = $params['product_name'];
            $model->category_id            = $params['product_category_id'];
            $model->logo_url               = $params['product_logo_url'];
            $model->share_url              = $params['product_share_url'];
            $model->wechat_share_url       = $params['product_wechat_share_url'];
            $model->mini_share_url         = $params['product_mini_share_url'];
            $model->image_urls             = $params['product_image_urls'];
            $model->desc                   = $params['product_desc'];
            $model->gift_points_proportion = $params['product_gift_points_proportion'];
            $model->tags                   = $params['product_tags'];
            $model->attr_info              = $params['product_attr_info'];
            $model->status                 = $params['product_status'];
            $model->save();

            foreach ($skuSaveData as &$item) {
                $item['product_id'] = $model->id;
            }

            //删除多余的sku
            $needDeleteSkuIds = [];
            $productSkuModels = (new ProductSkuModel())->where('product_id', $model->getData('id'))->select();
            foreach ($productSkuModels as $productSkuModel) {
                $needDeleteSkuIds[] = $productSkuModel->getData('id');
            }

            foreach ($skuSaveData as $key => $sku) {
                //sku_name
                foreach ($productSkuModels as $productSkuModel) {
                    if ($productSkuModel->getData('sku_name') === $sku['sku_name']) {
                        unset($skuSaveData[$key]);
                        $productSkuModel->stock         = $sku['stock'];
                        $productSkuModel->virtual_sales = $sku['virtual_sales'];
                        $productSkuModel->price         = $sku['price'];
                        $productSkuModel->cost_price    = $sku['cost_price'];
                        $productSkuModel->logo_url      = $sku['logo_url'];
                        $productSkuModel->save();
                        array_splice($needDeleteSkuIds, array_search($productSkuModel->getData('id'), $needDeleteSkuIds, true), 1);
                        break;
                    }
                }
            }
            foreach ($productSkuModels as $productSkuModel) {
                if (in_array($productSkuModel->getData('id'), $needDeleteSkuIds, true)) {
                    $productSkuModel->delete_time = NOW_TIME;
                    $productSkuModel->save();
                }
            }

            if ($skuSaveData) {
                $skuModel = new ProductSkuModel();
                $skuModel->saveAll($skuSaveData);
            }

            Db::commit();
            return retJson(Lang::PUTDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function deleteProduct()
    {
        throw new ParameterFailedException();
        $params      = self::getParam(['product_id']);
        (new ProductValidate())->goCheck(__FUNCTION__, $params);
        Db::startTrans();
        try {
            $model = ProductModel::where('id', $params['id'])->find();
            if (!$model) {
                throw new NotFoundException();
            }


            $otherModel = OtherModel::where('id', $params['id'])->find();
            if (!$otherModel) {
                throw new NotFoundException();
            }

            $model->delete_time = NOW_TIME;
            $model->save();

            //            Db::commit();

            return retJson(Lang::DELETEDone);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }
}